﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using CL_VisionCommu_Test.Helper;
using CLVisionTcpIP;
using DryIoc;
using ModbusMaster;
using TcpIPClient;
using static CL_VisionCommu_Test.Helper.Helper;

namespace CL_VisionCommu_Test.Device
{
    public class CommuTcpIPClientCaller
    {

        List<CommuTcpIPClient> masters = new List<CommuTcpIPClient>();

        List<CommunicationParameters> parameters = new List<CommunicationParameters>();

        public string ncOrTS = string.Empty;
        public string Init()
        {
            string ConnectedString = "";
            parameters = CommuConfiguration.GetParameters();
            for (int i = 0; i < parameters.Count; i++)
            {
                CommuTcpIPClient _master = new CommuTcpIPClient(parameters[i].Ip, parameters[i].Port, parameters[i], ncOrTS);


                ConnectedString += parameters[i].Ip + "_" + parameters[i].Port.ToString() + ":" + _master.NetworkIsOk.ToString() + "\r\n";
                masters.Add(_master);
            }
            return ConnectedString;
        }

        public int ReadTSConstantValue(int Index, string ConstantName)
        {
            int value = 0;
            if (masters.Count != 0 && masters.Count >= Index)
            {
                switch (ConstantName)
                {
                    case "RunStates":
                        value = Convert.ToInt32(masters[Index].rootClass["RunStates"]);
                        break;
                    case "TestplanStates":
                        value = Convert.ToInt32(masters[Index].rootClass["TestplanStates"]);
                        break;
                    case "ResultStates":
                        value = Convert.ToInt32(masters[Index].rootClass["ResultStates"]);
                        break;
                    case "Mode":
                        value = Convert.ToInt32(masters[Index].rootClass["Mode"]);
                        break;
                    case "HandShake00":
                        value = Convert.ToInt32(masters[Index].rootClass["HandShake00"]);
                        break;
                    case "HandShake01":
                        value = Convert.ToInt32(masters[Index].rootClass["HandShake01"]);
                        break;
                    case "HandShake02":
                        value = Convert.ToInt32(masters[Index].rootClass["HandShake02"]);
                        break;
                    case "HandShake03":
                        value = Convert.ToInt32(masters[Index].rootClass["HandShake03"]);
                        break;
                    case "HandShake04":
                        value = Convert.ToInt32(masters[Index].rootClass["HandShake04"]);
                        break;
                    case "HandShake05":
                        value = Convert.ToInt32(masters[Index].rootClass["HandShake05"]);
                        break;
                    case "HandShake06":
                        value = Convert.ToInt32(masters[Index].rootClass["HandShake06"]);
                        break;
                    case "HandShake07":
                        value = Convert.ToInt32(masters[Index].rootClass["HandShake07"]);
                        break;
                    default:
                        break;
                }
            }
            return value;
        }

        public bool WriteNCConstantValue(int Index, string ConstantName, double Value)
        {
            bool ret = false;
            try
            {
                if (masters.Count != 0 && masters.Count >= Index)
                {
                    switch (ConstantName)
                    {
                        case "Start check":
                            masters[Index].rootClass["Start check"] = (ushort)Value;
                            break;
                        case "Execute command":
                            masters[Index].rootClass["Execute command"] = (ushort)Value;
                            break;
                        case "IHandshake0":
                            masters[Index].rootClass["IHandshake0"] = (ushort)Value;
                            break;
                        case "IHandshake1":
                            masters[Index].rootClass["IHandshake1"] = (ushort)Value;
                            break;
                        case "IHandshake2":
                            masters[Index].rootClass["IHandshake2"] = (ushort)Value;
                            break;
                        case "IHandshake3":
                            masters[Index].rootClass["IHandshake3"] = (ushort)Value;
                            break;
                        case "IHandshake4":
                            masters[Index].rootClass["IHandshake4"] = (ushort)Value;
                            break;
                        case "IHandshake5":
                            masters[Index].rootClass["IHandshake5"] = (ushort)Value;
                            break;
                        case "IHandshake6":
                            masters[Index].rootClass["IHandshake6"] = (ushort)Value;
                            break;
                        case "IHandshake7":
                            masters[Index].rootClass["IHandshake7"] = (ushort)Value;
                            break;
                        case "Command code":
                            masters[Index].rootClass["Command code"] = (ushort)Value;
                            break;
                        case "Command parameter":
                            masters[Index].rootClass["Command parameter"] = (ushort)Value;
                            break;
                        default:
                            break;
                    }
                }
                masters[Index].Send(out _, out string error);
                ret = true;
                return ret;
            }
            catch (Exception)
            {
                ret = false;
                return ret;
            }
        }

        public int ReadNCConstantValue(int Index, string ConstantName)
        {
            int value = 0;
            if (masters.Count != 0 && masters.Count >= Index)
            {
                switch (ConstantName)
                {
                    case "System alive":
                        value = Convert.ToInt32(masters[Index].rootClass["System alive"]);
                        break;
                    case "Automatic mode ready":
                        value = (int)masters[Index].rootClass["Automatic mode ready"];
                        break;
                    case "System ready":
                        value = (int)masters[Index].rootClass["System ready"];
                        break;
                    case "Data valid":
                        value = (int)masters[Index].rootClass["Data valid"];
                        break;
                    case "Check routine result O.K":
                        value = (int)masters[Index].rootClass["Check routine result O.K"];
                        break;
                    case "Check routine result n.O.K":
                        value = (int)masters[Index].rootClass["Check routine result n.O.K"];
                        break;
                    case "Self test failed":
                        value = (int)masters[Index].rootClass["Self test failed"];
                        break;
                    case "Event log full":
                        value = (int)masters[Index].rootClass["Event log full"];
                        break;
                    case "OHandshake00":
                        value = (int)masters[Index].rootClass["OHandshake00"];
                        break;
                    case "OHandshake01":
                        value = (int)masters[Index].rootClass["OHandshake01"];
                        break;
                    case "OHandshake02":
                        value = (int)masters[Index].rootClass["OHandshake02"];
                        break;
                    case "OHandshake03":
                        value = (int)masters[Index].rootClass["OHandshake03"];
                        break;
                    case "OHandshake04":
                        value = (int)masters[Index].rootClass["OHandshake04"];
                        break;
                    case "OHandshake05":
                        value = (int)masters[Index].rootClass["OHandshake05"];
                        break;
                    case "OHandshake06":
                        value = (int)masters[Index].rootClass["OHandshake06"];
                        break;
                    case "OHandshake07":
                        value = (int)masters[Index].rootClass["OHandshake07"];
                        break;
                    case "Current check routine ID":
                        value = (int)masters[Index].rootClass["Current check routine ID"];
                        break;
                    case "Current security profile ID":
                        value = (int)masters[Index].rootClass["Current security profile ID"];
                        break;
                    case "Last command code":
                        value = (int)masters[Index].rootClass["Last command code"];
                        break;
                    default:
                        break;
                }
            }
            return value;
        }
        public bool WriteTSConstantValue(int Index, string ConstantName, double Value)
        {
            bool ret = false;
            try
            {
                if (masters.Count != 0 && masters.Count >= Index)
                {
                    switch (ConstantName)
                    {
                        case "Command":
                            masters[Index].rootClass["Command"] = (int)Value;
                            break;
                        case "ManFctNo":
                            masters[Index].rootClass["ManFctNo"] = (int)Value;
                            break;
                        case "ParaDinit1":
                            masters[Index].rootClass["ParaDinit1"] = (int)Value;
                            break;
                        case "ParaDinit2":
                            masters[Index].rootClass["ParaDinit2"] = (int)Value;
                            break;
                        case "ParaDinit3":
                            masters[Index].rootClass["ParaDinit3"] = (int)Value;
                            break;
                        case "ParaDinit4":
                            masters[Index].rootClass["ParaDinit4"] = (int)Value;
                            break;
                        case "ParaReal1":
                            masters[Index].rootClass["ParaReal1"] = (float)Value;
                            break;
                        case "ParaReal2":
                            masters[Index].rootClass["ParaReal2"] = (float)Value;
                            break;
                        case "ParaReal3":
                            masters[Index].rootClass["ParaReal3"] = (float)Value;
                            break;
                        case "ParaReal4":
                            masters[Index].rootClass["ParaReal4"] = (float)Value;
                            break;
                        case "Para1":
                            masters[Index].rootClass["Para1"] = (int)Value;
                            break;
                        case "Para2":
                            masters[Index].rootClass["Para2"] = (int)Value;
                            break;
                        case "HandShake00":
                            masters[Index].rootClass["HandShake00"] = (int)Value;
                            break;
                        case "HandShake01":
                            masters[Index].rootClass["HandShake01"] = (int)Value;
                            break;
                        case "HandShake02":
                            masters[Index].rootClass["HandShake02"] = (int)Value;
                            break;
                        case "HandShake03":
                            masters[Index].rootClass["HandShake03"] = (int)Value;
                            break;
                        case "HandShake04":
                            masters[Index].rootClass["HandShake04"] = (int)Value;
                            break;
                        case "HandShake05":
                            masters[Index].rootClass["HandShake05"] = (int)Value;
                            break;
                        case "HandShake06":
                            masters[Index].rootClass["HandShake06"] = (int)Value;
                            break;
                        case "HandShake07":
                            masters[Index].rootClass["HandShake07"] = (int)Value;
                            break;
                        case "StartSingle":
                            masters[Index].rootClass["StartSingle"] = (int)Value;
                            break;
                        case "Continuous":
                            masters[Index].rootClass["Continuous"] = (int)Value;
                            break;
                        case "CommandOnce":
                            masters[Index].rootClass["CommandOnce"] = (int)Value;
                            break;
                        case "BasSet":
                            masters[Index].rootClass["BasSet"] = (int)Value;
                            break;
                        case "WrkSet":
                            masters[Index].rootClass["WrkSet"] = (int)Value;
                            break;
                        default:
                            break;
                    }
                }
                masters[Index].Send(out _, out string error);
                ret = true;
                return ret;
            }
            catch (Exception)
            {
                ret = false;
                return ret;
            }
        }



        public bool WriteObject(int Index, ObjectItems objectItems)
        {
            bool ret = false;
            if (masters[Index] == null)
                return ret;
            try
            {
                for (int i = 0; i < objectItems.ItemsCount; i++)
                {
                    if (objectItems.Items[i].Array != 1)
                    {
                        DataType type = (DataType)Enum.Parse(typeof(DataType), objectItems.Items[i].Type);
                        string[] bufferdata = objectItems.Items[i].Default.TrimStart('[').TrimEnd(']').Split(',');
                        object data = null;

                        for (int a = 0; a < objectItems.Items[i].Array; a++)
                        {
                            switch (type)
                            {
                                case DataType.USHORT:
                                    data = Convert.ToUInt16(bufferdata[a]);
                                    masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name][a] = (ushort)data;

                                    break;
                                case DataType.INT:
                                    data = Convert.ToInt32(bufferdata[a]);
                                    masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name][a] = (int)data;
                                    break;
                                case DataType.FLOAT:
                                    data = Convert.ToSingle(bufferdata[a]);
                                    masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name][a] = (float)data;
                                    break;
                                case DataType.DOUBLE:
                                    data = Convert.ToDouble(bufferdata[a]);
                                    var v = masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name][a] = (double)data;
                                   
                                    break;

                                case DataType.BOOL:
                                    data = Convert.ToBoolean(bufferdata[a]);
                                    masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name][a] = (bool)data;
                                    break;
                                default:
                                    break;
                            }
                        }

                    }
                    else
                    {
                        DataType type = (DataType)Enum.Parse(typeof(DataType), objectItems.Items[i].Type);
                        object data = null;
                        switch (type)
                        {
                            case DataType.USHORT:
                                data = Convert.ToUInt16(objectItems.Items[i].Default);
                                masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name] = (ushort)data;

                                break;
                            case DataType.INT:
                                data = Convert.ToInt32(objectItems.Items[i].Default);
                                masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name] = (int)data;

                                break;
                            case DataType.FLOAT:
                                data = Convert.ToSingle(objectItems.Items[i].Default);
                                masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name] = (float)data;

                                break;
                            case DataType.DOUBLE:
                                data = Convert.ToDouble(objectItems.Items[i].Default);
                                masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name] = (double)data;

                                break;
                            case DataType.STRING:
                                data = objectItems.Items[i].Default ;
                                masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name] = (string)data;
                                break;
                            case DataType.BOOL:
                                data = Convert.ToBoolean(objectItems.Items[i].Default);
                                masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name] = (bool)data;

                                break;
                            default:
                                break;
                        }
                    }
                }
                masters[Index].Send(out _, out string error);
                return true;
            }
            catch (Exception)
            {
                return ret;
            }
        }


        public List<string> ReadObject(int Index, ObjectItems objectItems)
        {
            List<string> list = new List<string>();
            if (masters[Index] == null)
                return list;
            try
            {
                for (int i = 0; i < objectItems.ItemsCount; i++)
                {
                    if (objectItems.Items[i].Array != 1)
                    {
                        List<string> listbuffer = new List<string>();
                        DataType type = (DataType)Enum.Parse(typeof(DataType), objectItems.Items[i].Type);
                        string data = "";
                        for (int a = 0; a < objectItems.Items[i].Array; a++)
                        {
                            data = masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name][a].ToString();
                            listbuffer.Add(data);

                        }
                        list.Add("[" + string.Join(",", listbuffer.ToArray()) + "]");
                    }
                    else
                    {
                        DataType type = (DataType)Enum.Parse(typeof(DataType), objectItems.Items[i].Type);
                        string data = "";
                        data = masters[Index].rootClass["Object" + objectItems.ObjectID][objectItems.Items[i].Name].ToString();
                        list.Add(data);
                    }
                }
                return list;
            }
            catch (Exception ex)
            {
                return list;
            }
        }
    }
}
